#include "tools.h"
#include <chrono>
#include <thread>
extern "C"
{
#include <libavformat/avformat.h>
}
#include "demux_handler.h"
#include "thread_handler.h"

namespace lcf
{

    bool DemuxHandler::Seek(long long ms)
    {
        auto vp = demuxer_.CopyVideoPara();
        if (!vp)
            return false;
        auto pts = av_rescale_q(ms, {1, 1000}, *vp->timeBase);
        return demuxer_.Seek(pts, VideoIndex());
    }

    void DemuxHandler::Stop()
    {
        ThreadHandler::Stop();
        demuxer_.SetContext(nullptr);
    }

    bool DemuxHandler::Open(std::string url, int timeoutMs)
    {
        printf("DemuxHandler::Open begin!\n");
        demuxer_.SetContext(nullptr); // 断开之前的连接
        url_ = url;
        timeoutMs_ = timeoutMs;
        auto context = demuxer_.Open(url.c_str());
        if (!context)
            return false;
        demuxer_.SetContext(context);
        demuxer_.SetTimeOutMs(timeoutMs);
        printf("DemuxHandler::Open end!\n");
        return true;
    }

    void DemuxHandler::Main()
    {
        AVPacket pkt;

        while (!isExit_)
        {
            if (IsPause())
            {
                MSleep(1);
                continue;
            }

            if (!demuxer_.Read(&pkt))
            {
                // 读取失败
                std::cout << "-" << std::flush;
                if (!demuxer_.IsConnected())
                {
                    Open(url_, timeoutMs_);
                }

                std::this_thread::sleep_for(std::chrono::seconds(1));
                continue;
            }

            // 播放速度控制
            std::cout << "." << std::flush;
            if (syncType_ == XSYN_VIDEO &&
                pkt.stream_index == demuxer_.VideoIndex())
            {

                auto dur = demuxer_.RescaleToMs(pkt.duration, pkt.stream_index);
                if (dur <= 0)
                    dur = 40;
                // pkt.duration
                MSleep(dur);
            }

            Next(&pkt);
            av_packet_unref(&pkt);
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }

}